# -*- coding: utf-8 -*
import json
from solcx import compile_standard, install_solc
from web3 import Web3

# 引入sol文件
with open('./SimpleStorage.sol') as file:
    simple_storage_file = file.read();

# 安装预编译的二进制文件
# print('安装中');
# install_solc('0.6.0');

# 进行编译 编译后的结果是一个字典（python对象)
compiled_sol = compile_standard(
    {
        "language": "Solidity",
        "sources": {"SimpleStorage.sol": {"content": simple_storage_file}},
        "settings": {
            "outputSelection": {
                "*": {
                    "*": ["abi", "metadata", "evm.bytecode", "evm.bytecode.sourceMap"]
                }
            }
        },
    },
    solc_version="0.6.0",
)

# json.dump(dict, file_pointer)：将Python对象写入json文件
# dict：被转换的名称 file_pointer：打开文件的指针

# 将编译后的文件以JSON格式写入到compiled_code.json中
with open('compiled_code.json', 'w') as file:
    json.dump(compiled_sol, file);

# get bytecode
bytecode = compiled_sol["contracts"]["SimpleStorage.sol"]["SimpleStorage"]["evm"][
    "bytecode"
]["object"]

# get abi
#  json.loads将JSON格式的数据转化为字典 '{"name": "dzz"}' => {"name": "dzz"}
abi = json.loads(
    compiled_sol["contracts"]["SimpleStorage.sol"]["SimpleStorage"]["metadata"]
)["output"]["abi"]

# 连接到ganache
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:7545'));
chain_id = 1337;

# ganache提供的地址和私钥
my_address = '0x04F5dE5239f40E18a450cf37F501396022D4C1f3';
private_key = 'cdb436aeedde40f3fd593a43188e5142ec7874aeb58cc0662af0bd7eca9b6c42';

# 获取nonce
nonce = w3.eth.get_transaction_count(my_address);

#  创建合约类 <class 'web3._utils.datatypes.Contract'>
SimpleStorage = w3.eth.contract(abi=abi, bytecode=bytecode);

# 部署合约的步骤 1.构建交易 2.交易签名 3.发送交易

# 构建交易 返回交易信息 字典结构
transaction = SimpleStorage.constructor().buildTransaction({
    'chainId': chain_id,
    'from': my_address,
    'nonce': nonce
})

# 交易签名 <class 'eth_account.datastructures.SignedTransaction'>
signed_txn = w3.eth.account.sign_transaction(transaction, private_key=private_key)

# 发送交易
tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)

# 等待交易被打包进块
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(f"Contract deployed to {tx_receipt.contractAddress}")

contract_address = tx_receipt.contractAddress;


# 与已部署的合约进行交互
simple_storage = w3.eth.contract(abi=abi, address=contract_address)
print(f"Initial Stored Value {simple_storage.functions.retrieve().call()}")

# 构建交易
store_num_txn = simple_storage.functions.storeNum(666).buildTransaction({
    'chainId': chain_id,
    'from': my_address,
    'nonce': nonce + 1  
})

# 交易签名
signed_store_num = w3.eth.account.sign_transaction(store_num_txn, private_key=private_key);

# 发送交易
store_num_tx_hash = w3.eth.send_raw_transaction(signed_store_num.rawTransaction);

# 等待交易被打包进块
store_num_tx_receipt = w3.eth.wait_for_transaction_receipt(store_num_tx_hash)
print(store_num_tx_receipt.contractAddress)
print(f"Initial Stored Value {simple_storage.functions.retrieve().call()}")




